#include "globalconfig.h"

#include <QTextStream>
#include <QTextCodec>
#include <QSettings>
#include <iostream>
#include "zlog.h"

using namespace std;

int GlobalConfig::cabNumber = 0;
int GlobalConfig::cabActivated = 0;
int GlobalConfig::trainNumber = 0;
int GlobalConfig::trainSpeed = 0;
bool GlobalConfig::ATCComFlt;
bool GlobalConfig::xFAM = false;
bool GlobalConfig::xZeroSpeed = true;
int GlobalConfig::PISMode = PIS_ModeAuto;
bool GlobalConfig::xLocalActive = false;
int GlobalConfig::ATPFSStat[2];
bool GlobalConfig::ATPFS_Active = false;
QString GlobalConfig::password;
QString GlobalConfig::configFilePath;
int GlobalConfig::highVoltage=0;
uint8_t GlobalConfig::runDirection=0;
//---通信---
QList<TRDPDataPortInfo> GlobalConfig::recvTRDPList;
QList<TRDPDataPortInfo> GlobalConfig::sendTRDPList;
//---IO---
QList<InterfaceInfo> GlobalConfig::interfaceList[IO_TYPE_CNT];

QList<SpecialMessageInfo> GlobalConfig::spacialMessageList;
QList<LineInfo> GlobalConfig::stationList;
QList<EventInfo> GlobalConfig::eventList;
QMutex GlobalConfig::eventDatalocker;
QList<EventData> GlobalConfig::eventData;
QList<EventData> GlobalConfig::historyData;
QList<FaultInfo> GlobalConfig::faultList;
QList<FaultData> GlobalConfig::currentFaultData;
QList<FaultData> GlobalConfig::pastFaultData;
int GlobalConfig::faultLevelCnts[3];

int  GlobalConfig::SaloonHVACTemp[SaloonCnt+1];//+1 represent the whole train
//日志
QString GlobalConfig::operationFilePath;
bool GlobalConfig::xlog_init_ok;
//ATC
int GlobalConfig::atp_EB_test_success_delay;

GlobalConfig::GlobalConfig()
{

}

int GlobalConfig::readConfigFile(QString path)
{
    int ret = QFile().exists(path);
    if(!ret)
    {
        qDebug() << QString::fromUtf8("配置文件丢失或者失效！");
        return -1;
    }
    configFilePath = path;
    QSettings *setting = new QSettings(path, QSettings::IniFormat);

    // cabin
    setting->beginGroup("CABIN");
    cabNumber = setting->value("CabNumber").toInt();
    setting->endGroup();

    // password
    setting->beginGroup("PASSWORD");
    password = setting->value("Password").toString();
    setting->endGroup();

    //atp test success delay
    setting->beginGroup("ATC");
    atp_EB_test_success_delay = setting->value("ATPEBTestSuccessDelay").toInt();
    setting->endGroup();
    delete setting;

    return 0;
}

void GlobalConfig::writePasswd(QString passwd)
{
    password = passwd;

    QSettings *setting = new QSettings(configFilePath, QSettings::IniFormat);
    setting->beginGroup("PASSWORD");
    setting->setValue("Password", passwd);
    setting->endGroup();
    delete setting;
}
//------------------    读通讯配置文件    ---------------------------------
int GlobalConfig::readRecvTRDPDataFile(QString path)
{
    QFile file(path);
    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream stream(&file);
        QString fileVersion = QString();
        QString str = stream.readLine(); // title
        int ret = 0;
        while(!stream.atEnd())
        {
            str = stream.readLine();
            QStringList strList = str.split(",");
            if(strList.at(0) == QString("[Version]"))
            {
                fileVersion = strList.at(1);
                cout << "RecvTRDPDataFile Version: " << fileVersion.toLatin1().data() << endl;
                continue;
            }

            if(strList.at(0) == QChar('#'))
            {
                Handle_CFG_TRDPPort(strList);
                continue;
            }

            if((ret = Handle_CFG_TRDPNode(strList)) < 0)
                return ret;

            if(strList.at(6) == "EVENT")
            {
                if((ret =  Handle_CFG_EVENT(strList)) < 0)
                    return ret;
            }

            if(strList.at(6) == "IO")
            {
                if((ret =  Handle_CFG_IO(strList)) < 0)
                    return ret;
            }
        }
        file.close();
        return 0;
    }
    else
    {
        qDebug() << QString("RecvTRDPR接口文件读取失败！");
        return -1;
    }
}

int GlobalConfig::Handle_CFG_TRDPPort(const QStringList &strlist)
{
    TRDPDataPortInfo portInfo;
    QString comid_str = strlist.at(1);
    //判断左右板卡，配置comid
    QString srcsystem = strlist.at(6);
    if(srcsystem == "ATC")
    {
        if(getCurrentBoardId() == 1)
            comid_str.replace('X','4');
        else
            comid_str.replace('X','3');

        if(cabNumber == 6)
            comid_str.replace('Y','6');
        else
            comid_str.replace('Y','1');
    }
    if(srcsystem == "PUBLIC-VCU")
    {
        if(getCurrentBoardId() == 1)
            comid_str.replace('X','2');
        else
            comid_str.replace('X','1');
    }
    if(srcsystem == "PUBLIC-VSCU")
    {
        if(getCurrentBoardId() == 1)
            comid_str.replace('X','4');
        else
            comid_str.replace('X','3');
    }
    if(srcsystem == "VCU1")
    {
        if(getCurrentBoardId() == 1)
            comid_str.replace('X','2');
        else
            comid_str.replace('X','1');
    }
    if(srcsystem == "VCU2")
    {
        if(getCurrentBoardId() == 1)
            comid_str.replace('X','6');
        else
            comid_str.replace('X','5');
    }
    if(srcsystem == "VCU3")
    {
        if(getCurrentBoardId() == 1)
            comid_str.replace('X','4');
        else
            comid_str.replace('X','3');
    }
    portInfo.comid = comid_str.toUInt();
    portInfo.size = strlist.at(2).toUInt();
    portInfo.period = strlist.at(3).toUInt();

    TRDPSrcIPInfo tempsrcipInfo;
    tempsrcipInfo.index = 0;
    tempsrcipInfo.xHBnormal = false;
    QString src_ip_str = strlist.at(4);
    //判断左右板卡，配置src ip
    tempsrcipInfo.srcip = src_ip_str;
    tempsrcipInfo.HBcounter = 0;
    tempsrcipInfo.preHBvalue = 0;
    portInfo.srcipinfo = tempsrcipInfo;

    portInfo.type = RECV;
    portInfo.destip = strlist.at(5);
    portInfo.dduFlt = true;
    portInfo.node.clear();
    portInfo.subsys = strlist.at(6);
    recvTRDPList.append(portInfo);
    return 0;
}

int GlobalConfig::Handle_CFG_TRDPNode(const QStringList &strlist)
{
    TRDPDataNodeInfo info;
    info.index = QString().setNum(recvTRDPList[recvTRDPList.size()-1].node.size());
    info.varName = strlist.at(1);
    info.description = strlist.at(2);
    QString node_type_str = strlist.at(3);
    if(node_type_str == QString("BOOLEAN1") || node_type_str == QString("BOOL"))
        info.size = 1;
    else if(node_type_str == QString("UNSIGNED2"))
        info.size = 2;
    else if(node_type_str == QString("UNSIGNED3"))
        info.size = 3;
    else if(node_type_str == QString("UNSIGNED4"))
        info.size = 4;
    else if(node_type_str == QString("UNSIGNED5"))
        info.size = 5;
    else if(node_type_str == QString("UNSIGNED6"))
        info.size = 6;
    else if(node_type_str == QString("UNSIGNED7"))
        info.size = 7;
    else if(node_type_str == QString("UNSIGNED8") || node_type_str == QString("BYTE") || node_type_str == QString("USINT") || node_type_str == QString("INTEGER8"))
        info.size = 8;
    else if(node_type_str == QString("UNSIGNED16") || node_type_str == QString("WORD") || node_type_str == QString("INT") || node_type_str == QString("UINT") || node_type_str == QString("INTEGER16"))
        info.size = 16;
    else if(node_type_str == QString("UNSIGNED24"))
        info.size = 24;
    else if(node_type_str == QString("UNSIGNED32") || node_type_str == QString("DWORD") || node_type_str == QString("UDINT"))
        info.size = 32;
    else
    {
        qDebug() << "NODE TYPE ERROR:" << strlist.at(0) << strlist.at(1) << node_type_str;
        return -1;
    }

    info.byte = strlist.at(4).toInt();
    info.bit = (unsigned char)strlist.at(5).toInt();
    if(info.bit > 7)
    {
        qDebug() << "NODE BIT ERROR:" << strlist.at(0) << strlist.at(1) << info.bit;
        return -2;
    }
    recvTRDPList[recvTRDPList.size()-1].node.append(info);
    return 0;
}

int GlobalConfig::Handle_CFG_EVENT(const QStringList &strlist)
{
    if(strlist.size() != 10)
    {
        qDebug()<< "Event node length error:" << strlist.at(0) << strlist.at(1);
        return -3;
    }
    int byte = strlist.at(4).toInt();
    int bit = (unsigned char)strlist.at(5).toInt();
    if(!strlist.at(6).isEmpty())
    {
        EventInfo node;
        node.id = recvTRDPList.size()*10000 + byte*10 + bit;

        int car = strlist.at(1).right(1).toInt();
        if(car>0 && car<7 && (strlist.at(1).right(2).left(1) == QString("_") || strlist.at(1).right(3).left(2) == QString("_C")))
            node.car = QString().setNum(car);
        else
            node.car = QString("-");

        node.description = strlist.at(2);
        node.level = strlist.at(7);
        if(node.level == "")
            qDebug()<<"Event node has no level"<< strlist.at(0) << strlist.at(1);
        node.code = strlist.at(8);
        node.hint = node.hint = QString(strlist.at(9)).replace("<comma>", "，").replace("<br>", "\n");;
        if(node.code.isEmpty())
            node.code = QString("-");
        eventList.append(node);
    }
    return 0;
}

int GlobalConfig::Handle_CFG_IO(const QStringList &strlist)
{
    if(strlist.size() != 10)
    {
        qDebug() << "IO node length error:"<< strlist.at(0) << strlist.at(1);
        return -4;
    }

    int byte = strlist.at(4).toInt();
    int bit = (unsigned char)strlist.at(5).toInt();
    InterfaceInfo node;
    node.id = recvTRDPList.size()*10000 + byte*10 + bit;
    node.description = strlist.at(2);
    node.pinId = strlist.at(9);
    node.sys = strlist.at(6);
    node.value = 0;
    int type = -1;
    if(strlist.at(8).left(2) == QString("AI") || strlist.at(8).left(2) == QString("AO"))
        type = AI;
    else if(strlist.at(8).left(2) == QString("DI") && strlist.at(7).left(6) == QString("RIOM10"))
        type = RIOM_DI_TC;
    else if(strlist.at(8).left(2) == QString("DI") && strlist.at(7).left(5) == QString("LCU11"))
        type = LCU_DI_Tc;
    else if(strlist.at(8).left(2) == QString("DI") && strlist.at(7).left(5) == QString("LCU21"))
        type = LCU_DI_Mp;
    else if(strlist.at(8).left(2) == QString("DI") && strlist.at(7).left(5) == QString("LCU31"))
        type = LCU_DI_M;
    else if(strlist.at(8).left(2) == QString("DI") && strlist.at(7).left(4) == QString("EVR4"))
        type = EVR_DI_M;
    else if(strlist.at(8).left(2) == QString("DO") && strlist.at(7).contains("LCU"))
        type = LCU_DO;

    if(type == -1)
    {
        qDebug() << "IO TYPE ERROR:" << strlist.at(1);
        return -5;
    }
    int car = strlist.at(7).right(1).toInt();
    node.car = car;
    int maxindex = -1;
    bool repeat = false;
    for(int k=0; k<interfaceList[type].size(); ++k)
    {
        if(interfaceList[type].at(k).description == node.description && interfaceList[type].at(k).pinId == node.pinId)
        {
            repeat = true;
            node.index = interfaceList[type].at(k).index;
            break;
        }
        if(interfaceList[type].at(k).index > maxindex)
            maxindex = interfaceList[type].at(k).index;
    }
    if(!repeat)
        node.index = maxindex + 1;
    interfaceList[type].append(node);
    return 0;
}

int GlobalConfig::getRecvVarIndex(int comidIndex, uint varoffset)
{
    if(comidIndex < 0 || comidIndex>recvTRDPList.length())
        return -1;
    unsigned int byte = varoffset/10;
    unsigned char bit = varoffset%10;
    for(int i=0;i<recvTRDPList.at(comidIndex).node.length();i++)
    {
        if(byte == recvTRDPList.at(comidIndex).node.at(i).byte &&
           bit == recvTRDPList.at(comidIndex).node.at(i).bit)
            return i;
    }
    return -1;
}

int GlobalConfig::readSendTRDPDataFile(QString path)
{
    QFile file(path);
    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream stream(&file);
        QString fileVersion = QString();
        QString str = stream.readLine(); // title
        while(!stream.atEnd())
        {
            str = stream.readLine();
            QStringList strList = str.split(",");
            if(strList.at(0) == QString("[Version]"))
            {
                fileVersion = strList.at(1);
                cout <<  "SendTRDPDataFile Version: " << fileVersion.toLatin1().data()  << endl;
                continue;
            }
            if(strList.at(0) == QChar('#'))
            {
                TRDPDataPortInfo portInfo;
                QString comidstr = strList.at(1);
                QString destsystem = strList.at(6);
                if(cabNumber == 1)
                    comidstr.replace(QChar('Y'), QChar('1'));
                else if(cabNumber == 6)
                    comidstr.replace(QChar('Y'), QChar('6'));

                if(getCurrentBoardId() == 1)
                {
                    if(destsystem == "VCU")
                        comidstr.replace(QChar('X'), QChar('2'));
                    else if(destsystem == "ATC")
                        comidstr.replace(QChar('X'), QChar('4'));
                }
                else
                {
                    if(destsystem == "VCU")
                        comidstr.replace(QChar('X'), QChar('1'));
                    else if(destsystem == "ATC")
                        comidstr.replace(QChar('X'), QChar('3'));
                }
                portInfo.comid = comidstr.toUInt(NULL, 10);
                portInfo.size = strList.at(2).toUInt();
                portInfo.period = strList.at(3).toUInt();

                TRDPSrcIPInfo tempsrcipInfo;
                tempsrcipInfo.index = 0;
                tempsrcipInfo.xHBnormal = true;
                QString ownipstr = strList.at(4); //ownIP
                if(cabNumber == 1)
                    ownipstr.replace(QChar('Y'), QChar('1'));
                else if(cabNumber == 6)
                    ownipstr.replace(QChar('Y'), QChar('6'));

                if(getCurrentBoardId() == 1)
                    ownipstr.replace(QChar('X'), QChar('1'));
                else
                    ownipstr.replace(QChar('X'), QChar('0'));
                tempsrcipInfo.srcip = ownipstr;
                portInfo.srcipinfo = tempsrcipInfo;

                portInfo.destip =  strList.at(5);      //multicast IP
                portInfo.type = SEND;
                portInfo.node.clear();
                sendTRDPList.append(portInfo);
                continue;
            }

            TRDPDataNodeInfo info;
            info.varName = strList.at(1);
            info.description = strList.at(2);
            if(strList.at(3) == QString("BOOLEAN1") || strList.at(3) == QString("BOOL"))
                info.size = 1;
            else if(strList.at(3) == QString("UNSIGNED8") || strList.at(3) == QString("BYTE") || strList.at(3) == QString("USINT"))
                info.size = 8;
            else if(strList.at(3) == QString("UNSIGNED16") || strList.at(3) == QString("WORD") || strList.at(3) == QString("INT") || strList.at(3) == QString("UINT") || strList.at(3) == QString("INTEGER16"))
                info.size = 16;
            else if(strList.at(3) == QString("UNSIGNED32") || strList.at(3) == QString("DWORD") || strList.at(3) == QString("UDINT"))
                info.size = 32;
            else
                qDebug() << "TYPE ERROR:" << strList.at(1) << strList.at(3);
            info.byte = strList.at(4).toInt();
            info.bit = (unsigned char)strList.at(5).toInt();
            sendTRDPList[sendTRDPList.size()-1].node.append(info);
        }
        file.close();
        return 0;
    }
    else
    {
        qDebug() << QString("SendTRDP数据接口文件读取失败！");
        return -1;
    }
}
//------------------    IO接口信息    ---------------------------------
int GlobalConfig::getInterfaceInfo(int id, int value, InterfaceInfo &info)
{
    for(int i=0; i<IO_TYPE_CNT; ++i)
    {
        for(int j=0; j<interfaceList[i].size(); ++j)
        {
            if(interfaceList[i][j].id == (uint)id)
            {
                info = interfaceList[i][j];
                interfaceList[i][j].value = value;
                return i;
            }
        }
    }
    qDebug("undefined interface info %d!", id);
    return -1;
}

int GlobalConfig::readRouteFile(QString path)
{
    QFile file(path);
    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream stream(&file);
        QString fileVersion = QString();
        QString str = stream.readLine(); // title
        while(!stream.atEnd())
        {
            str = stream.readLine();
            QStringList strList = str.split(",");
            if(strList.at(0) == QString("[Version]"))
            {
                fileVersion = strList.at(1);
                cout << "RouteFile Version: " << fileVersion.toLatin1().data() << endl;
                continue;
            }
            if(strList.at(0) == "#")
            {
                LineInfo route;
                route.routeName = strList.at(1);
                route.startName = strList.at(2);
                route.destName = strList.at(3);
                route.stationCount = 0;
                route.station.clear();
                stationList.append(route);
                continue;
            }

            StationInfo info;
            info.stationId = strList.at(0).toUInt();
            info.name = strList.at(1);
            stationList[stationList.size()-1].station.append(info);
            stationList[stationList.size()-1].stationCount++;
        }
        file.close();
        cout << "read route file success" << endl;
        return 0;
    }
    else
    {
        qDebug() << QString("线路信息文件读取失败！");
        return -1;
    }
}

int GlobalConfig::getEventInfo(uint id, EventInfo &info)
{
    for(int i=0; i<eventList.size(); ++i)
    {
        if(eventList.at(i).id == id)
        {
            info = eventList.at(i);
            return 0;
        }
    }
    qDebug("undefined event info %d!", id);
    return -1;
}

int GlobalConfig::addEvent(uint id, unsigned long value)
{
    bool exist = false;
    int index = -1;
    QMutexLocker locker(&eventDatalocker);
    for(int i=0; i<eventData.size(); ++i)
    {
        if(eventData.at(i).event.id == id)
        {
            exist = true;
            index = i;
            break;
        }
    }
    EventData data;
    if(getEventInfo(id, data.event))
        return -2;
    if(exist)
    {
        data.startTime = eventData.at(index).startTime;
        eventData.removeAt(index);
    }
    else
    {
        time(&data.startTime);
    }
    data.event.description.replace("<X>", QString().setNum(value));
    data.ack = false;
    data.endTime = 0;
    updateFaultLevelCnt(data,true);
    eventData.append(data);
    return 0;
}

int GlobalConfig::removeEvent(uint id)
{
    QMutexLocker locker(&eventDatalocker);
    for(int i=0; i<eventData.size(); ++i)
    {
        if(eventData.at(i).event.id == id)
        {
            EventData data = eventData.at(i);
            time(&data.endTime);
            historyData.append(data);
            RecordLastFaults(data);
            updateFaultLevelCnt(data,false);
            eventData.removeAt(i);
            break;
        }
    }
    return 0;
}

void GlobalConfig::ackEvent(uint id)
{
    QMutexLocker locker(&eventDatalocker);
    for(int i=eventData.size()-1; i>=0; --i)
    {
        if(eventData.at(i).event.id == id)
        {
            eventData[i].ack = true;
            break;
        }
    }
}

int GlobalConfig::getEventData(int index, EventData &data)
{
    QMutexLocker locker(&eventDatalocker);
    if(index>=0 && index<eventData.size())
    {
        data = eventData.at(index);
        return 0;
    }
    return -1;
}

void GlobalConfig::updateFaultLevelCnt(const EventData &data, bool xAdd)
{
    if(data.event.level == "4")
        return;
    if(xAdd)
        faultLevelCnts[data.event.level.toUInt()-1]++;
    else
        faultLevelCnts[data.event.level.toUInt()-1]--;
}

int GlobalConfig::getHighestFaultLevel()
{
    QMutexLocker locker(&eventDatalocker);
    if(faultLevelCnts[0] > 0)
        return 1;
    if(faultLevelCnts[1] > 0)
        return 2;
    if(faultLevelCnts[2] > 0)
        return 3;

    return 0;
}

int GlobalConfig::getLatestTopLevelEvent(EventData &data)
{
    QMutexLocker locker(&eventDatalocker);
    if(eventData.isEmpty())
        return -1;
    for(int i=eventData.size()-1; i>=0; --i)
    {
        if(eventData.at(i).event.level == "1")
        {
            data = eventData.at(i);
            return 0;
        }
    }
    for(int i=eventData.size()-1; i>=0; --i)
    {
        if(eventData.at(i).event.level == "2")
        {
            data = eventData.at(i);
            return 0;
        }
    }
    for(int i=eventData.size()-1; i>=0; --i)
    {
        if(eventData.at(i).event.level == "i")
        {
            data = eventData.at(i);
            return 0;
        }
    }
    return -1;
}

int GlobalConfig::getHistoryData(int index, EventData &data)
{
    if(index>=0 && index<historyData.size())
    {
        data = historyData.at(index);
        return 0;
    }
    return -1;
}

int GlobalConfig::getEventResetID(QString type)
{
    for(int i=0; i<recvTRDPList.size(); ++i)
    {
        for(int j=0; j<recvTRDPList.at(i).node.size(); ++j)
        {
            if(recvTRDPList.at(i).node.at(j).varName.contains(type))
            {
                return i*1000 + j;
            }
        }
    }
    qDebug() << "undefined reset event type:" << type;
    return -1;
}

int GlobalConfig::readSpecialMessageFile(QString path)
{
    QFile file(path);
    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream stream(&file);
        QString fileVersion = QString();
        QString str = stream.readLine(); // title
        while(!stream.atEnd())
        {
            str = stream.readLine();
            QStringList strlist = str.split(",");
            SpecialMessageInfo info;
            info.id = strlist.at(0).toUInt();
            info.name = strlist.at(1);
            spacialMessageList.append(info);
        }
        file.close();
        cout << "read spacial message success" << endl;
        return 0;
    }
    else
    {
        qDebug() << QString("特殊信息文件读取失败！");
        return -1;
    }
}

int GlobalConfig::getRouteIndexByName(QString name)
{
    for(int i=0; i<stationList.size(); ++i)
    {
        if(stationList.at(i).routeName == name)
            return i;
    }
    return -1;
}

int GlobalConfig::getStationIndexByName(int route, QString name)
{
    if(route < stationList.size())
    {
        for(int i=0; i<stationList.at(route).stationCount; ++i)
        {
            if(stationList.at(route).station.at(i).name == name)
                return i;
        }
    }
    return -1;
}

QString GlobalConfig::getStationNameByID(uint id)
{
    for(int i=0; i<stationList.size(); ++i)
    {
        for(int j=0; j<stationList.at(i).stationCount; ++j)
        {
            if(stationList.at(i).station.at(j).stationId == id)
                return stationList.at(i).station.at(j).name;
        }
    }
    return QString("--");
}

void GlobalConfig::setSalHVACTemp(uint8_t sal,int temp)
{
    SaloonHVACTemp[sal] = temp;
}

int GlobalConfig::getCurrentBoardId()
{
#ifdef RUN_IN_BOARD
       return avic_get_currentBoardId() ;
#else
       return 1;
#endif
}

int GlobalConfig::parseOperationFile(QString path)
{
    operationFilePath = path;
    QDateTime now = QDateTime::currentDateTime();
    addOperationInfo(QString("%1\tHMI程序启动").arg(now.toString("yyyy-MM-dd hh:mm:ss")), true);
    if(!QFile(path).exists())
    {
        cout << "no operation file exists !" << endl;
        return -2;
    }
    QFile file(path);
    int totalLine = 0;
    int oldLine = 0;
    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream stream(&file);
        while(!stream.atEnd())
        {
            QString str = stream.readLine();
            totalLine++;
            QStringList strlist = str.split("\t");
            QDateTime dt = QDateTime::fromString(strlist.at(0), "yyyy-MM-dd hh:mm:ss");
            if(dt.secsTo(now) > 72*3600)
                oldLine++;
            else
                continue;
        }
        file.close();
#ifdef RUN_IN_BOARD
        QString cmd = QString("tail -n %1 %2 > temp").arg(totalLine-oldLine).arg(operationFilePath);
        system(cmd.toLatin1().data());
        file.remove();
        QFile("temp").rename(operationFilePath);
#endif
        return 0;
    }
    else
    {
        qDebug() << QString("OPERATION文件读取失败！");
        return -1;
    }
}

void GlobalConfig::addOperationInfo(QString op, bool boot)
{
    QFile file(operationFilePath);
    if(file.open(QIODevice::ReadWrite | QIODevice::Append))
    {
        QString str;
        if(!boot)
        {
            QStringList strlist;
            strlist << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << op << QString("hv:%1").arg(highVoltage) << QString("speed:%1").arg(trainSpeed);
            str = strlist.join("\t") + QString("\n");
        }
        else
            str = op + QString("\n");
        file.write(str.toUtf8());
        file.flush();
        file.close();
    }
}

void GlobalConfig::RecordLastFaults(EventData info)
{
    QFile file("last200faults.csv");
    if(file.open(QIODevice::Append))
    {
        QString onefault =  info.event.car+";"+
                            info.event.description+";"+
                            info.event.code+";"+
                            info.event.level+";"+
                            QString("%1").arg(info.startTime)+";"+
                            QString("%1").arg(info.endTime)+"\n";
        QTextStream stream(&file);
        stream<<onefault;
    }
    else
    {
        qDebug()<<"error write to file";
    }
    file.close();
}

void GlobalConfig::ReadLast200Faults()
{
    QFile file("last200faults.csv");
    QFile file_tmp("fault_tmp.csv");

    int LastFaultSum=0;
    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream rstream(&file);
            while(!rstream.atEnd())
            {
                LastFaultSum++;
                rstream.readLine();
            }
            file.seek(0);
            if(file_tmp.open(QIODevice::WriteOnly))
            {
                QTextStream wstream(&file_tmp);
                for(int j=0;j<LastFaultSum-200;j++)
                {
                    rstream.readLine();
                }
                while(!rstream.atEnd())
                {
                    QString strline=rstream.readLine();
                    wstream<<strline<<"\n";
                    EventData info_t;
                    QStringList strlist = strline.split(";");
                    for(int i=0;i<strlist.length();i++)
                    {
                        switch(i)
                        {
                        case 0:
                            info_t.event.car = strlist.at(i);
                            break;
                        case 1:
                            info_t.event.description = strlist.at(i);
                            break;
                        case 2:
                            info_t.event.code = strlist.at(i);
                            break;
                        case 3:
                            info_t.event.level = strlist.at(i);
                            break;
                        case 4:
                            info_t.startTime = strlist.at(i).toInt();
                            break;
                        case 5:
                            info_t.endTime = strlist.at(i).toInt();
                            break;
                        }
                    }
                    historyData.append(info_t);
                }
            }
    }
    file.close();
    file_tmp.close();
    file.remove();
    file_tmp.rename("last200faults.csv");
}

void GlobalConfig::InitDDULog()
{
#ifdef RUN_IN_BOARD
    int rc;
    rc = dzlog_init("hf8_ddu_log.conf", "hf8ddu");

    if (rc) {

        printf("init zlog failed:%d\n",rc);
        xlog_init_ok = false;
    }
    printf("init zlog successfully\n");
    xlog_init_ok = true;
#endif
}

void GlobalConfig::writeLog(QString log)
{
#ifdef RUN_IN_BOARD
    if(!xlog_init_ok)
        return;

    QByteArray ba = log.toLatin1();
    char* w_log = ba.data();
    dzlog_info("%s",w_log);
#endif
}
